﻿namespace UnityEngine
{
    using System;
    using System.Runtime.InteropServices;

    internal class SendMouseEvents
    {
        private static HitInfo[] m_LastHit = new HitInfo[] { new HitInfo(), new HitInfo() };
        private static HitInfo[] m_MouseDownHit = new HitInfo[] { new HitInfo(), new HitInfo() };

        [NotRenamed]
        private static void DoSendMouseEvents(int mouseUsed, int skipRTCameras)
        {
            HitInfo[] infoArray = new HitInfo[] { new HitInfo(), new HitInfo() };
            Vector3 mousePosition = Input.mousePosition;
            Camera[] allCameras = Camera.allCameras;
            if (mouseUsed == 0)
            {
                foreach (Camera camera in allCameras)
                {
                    if (((skipRTCameras == 0) || (camera.targetTexture == null)) && camera.pixelRect.Contains(mousePosition))
                    {
                        RaycastHit hit;
                        GUILayer component = (GUILayer) camera.GetComponent(typeof(GUILayer));
                        if (component != null)
                        {
                            GUIElement element = component.HitTest(mousePosition);
                            if (element != null)
                            {
                                infoArray[0].target = element.gameObject;
                                infoArray[0].camera = camera;
                            }
                        }
                        if ((camera.farClipPlane > 0f) && Physics.Raycast(camera.ScreenPointToRay(mousePosition), out hit, camera.farClipPlane, camera.cullingMask & -5))
                        {
                            if (hit.rigidbody != null)
                            {
                                infoArray[1].target = hit.rigidbody.gameObject;
                                infoArray[1].camera = camera;
                            }
                            else
                            {
                                infoArray[1].target = hit.collider.gameObject;
                                infoArray[1].camera = camera;
                            }
                        }
                        else if ((camera.clearFlags == CameraClearFlags.Skybox) || (camera.clearFlags == CameraClearFlags.Color))
                        {
                            infoArray[1].target = null;
                            infoArray[1].camera = null;
                        }
                    }
                }
            }
            for (int i = 0; i < 2; i++)
            {
                bool mouseButtonDown = Input.GetMouseButtonDown(0);
                bool mouseButton = Input.GetMouseButton(0);
                if (mouseButtonDown)
                {
                    if (infoArray[i] != 0)
                    {
                        m_MouseDownHit[i] = infoArray[i];
                        m_MouseDownHit[i].SendMessage("OnMouseDown");
                    }
                }
                else if (!mouseButton)
                {
                    if (m_MouseDownHit[i] != 0)
                    {
                        if (HitInfo.Compare(infoArray[i], m_MouseDownHit[i]))
                        {
                            m_MouseDownHit[i].SendMessage("OnMouseUpAsButton");
                        }
                        m_MouseDownHit[i].SendMessage("OnMouseUp");
                        m_MouseDownHit[i] = new HitInfo();
                    }
                }
                else if (m_MouseDownHit[i] != 0)
                {
                    m_MouseDownHit[i].SendMessage("OnMouseDrag");
                }
                if (HitInfo.Compare(infoArray[i], m_LastHit[i]))
                {
                    if (infoArray[i] != 0)
                    {
                        infoArray[i].SendMessage("OnMouseOver");
                    }
                }
                else
                {
                    if (m_LastHit[i] != 0)
                    {
                        m_LastHit[i].SendMessage("OnMouseExit");
                    }
                    if (infoArray[i] != 0)
                    {
                        infoArray[i].SendMessage("OnMouseEnter");
                        infoArray[i].SendMessage("OnMouseOver");
                    }
                }
                m_LastHit[i] = infoArray[i];
            }
        }

        [StructLayout(LayoutKind.Sequential)]
        private struct HitInfo
        {
            public GameObject target;
            public Camera camera;
            public void SendMessage(string name)
            {
                this.target.SendMessage(name, null, SendMessageOptions.DontRequireReceiver);
            }

            public static bool Compare(SendMouseEvents.HitInfo lhs, SendMouseEvents.HitInfo rhs)
            {
                return ((lhs.target == rhs.target) && (lhs.camera == rhs.camera));
            }

            public static implicit operator bool(SendMouseEvents.HitInfo exists)
            {
                return ((exists.target != null) && (exists.camera != null));
            }
        }
    }
}

